package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

// 目标类：包含不同构造器的User类
class User {
    private String name;
    private int age;

    // 无参构造器（默认或显式定义）
    public User() {
        System.out.println("调用无参构造器");
    }

    // 带参构造器
    public User(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("调用带参构造器：name=" + name + ", age=" + age);
    }

    // 私有构造器（演示访问私有成员）
    private User(String name) {
        this.name = name;
        System.out.println("调用私有构造器：name=" + name);
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}

public class CreateObject {
    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException,
            NoSuchMethodException, InvocationTargetException {

        // 1. 获取Class对象
        Class<?> userClass = Class.forName("User");

        // 方式1：调用无参构造器（已过时，不推荐）
        // User user1 = (User) userClass.newInstance(); // JDK 9+ 已过时

        // 方式2：通过Constructor调用无参构造器（推荐）
        Constructor<?> constructor1 = userClass.getConstructor(); // 获取无参构造器
        User user1 = (User) constructor1.newInstance(); // 创建对象

        // 方式3：调用带参构造器
        Constructor<?> constructor2 = userClass.getConstructor(String.class, int.class); // 指定参数类型
        User user2 = (User) constructor2.newInstance("张三", 20); // 传入参数值

        // 方式4：调用私有构造器（需设置accessible为true）
        Constructor<?> constructor3 = userClass.getDeclaredConstructor(String.class); // getDeclaredConstructor获取所有构造器
        constructor3.setAccessible(true); // 取消访问检查（关键步骤）
        User user3 = (User) constructor3.newInstance("李四");

        System.out.println("\n创建的对象：");
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user3);
    }
}
